<template>
  <div class="threejs-container" ref="threejsContainerRef"></div>
</template>

<script setup>
import { ref, onMounted } from "vue";
import {
  WebGLRenderer,
  Scene,
  PerspectiveCamera,
  Vector3,
  Mesh,
  BoxGeometry,
  MeshStandardMaterial,
  AmbientLight,
  MOUSE,
  PointLight 
} from "three";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";

const threejsContainerRef = ref(null);
const threejsContainer = ref(null);

class ThreeEngine {
  // 挂载的 DOM
  dom = null;
  // 场景
  scene = null;
  // 构造器函数
  constructor(dom) {
    let renderer = new WebGLRenderer(
        {
          antialias: true, // 抗锯齿
        }
    ); // 创建渲染器
    dom.appendChild(renderer.domElement); // 渲染器挂载到 DOM
    renderer.setSize(dom.clientWidth, dom.clientHeight, true); // 设置渲染器尺寸

    let scene = new Scene(); // 实例化场景

    let camera = new PerspectiveCamera(
      45,
      dom.clientWidth / dom.clientHeight,
      1,
      1000
    ); // 实例化相机
    camera.position.set(50, 50, 50); // 设置相机位置
    camera.lookAt(new Vector3(0, 0, 0)); // 设置相机朝向
    camera.up = new Vector3(0, 1, 0); // 设置相机自身的方向

    renderer.render(scene, camera); // 渲染
    // renderer.setClearColor("#DEE1E6"); // 设置渲染器的颜色

    this.dom = dom;
    this.scene = scene; // 实例化场景

    let orbitControls = new OrbitControls(camera, renderer.domElement);
    orbitControls.mouseButtons = {
      LEFT: null,
      MIDDLE: MOUSE.DOLLY, // 中键缩放
      RIGHT: MOUSE.ROTATE, // 右键旋转
    };

    let animate = () => {
      renderer.render(scene, camera); // 渲染器渲染场景和相机
      requestAnimationFrame(animate);
    };
    animate();
  }

  /**
   * 向场景中添加模型
   * @param  {...any} object 模型列表
   */
  addObject(...object) {
    object.forEach((elem) => {
      this.scene.add(elem); // 场景添加模型
    });
  }
}

let allBaseObject = []; // 所有基础模型
const cube = new Mesh(
  new BoxGeometry(20, 20, 20),
  new MeshStandardMaterial({
    // 设置材质
    color: "rgb(36, 172, 242)", // 设置材质的颜色
  })
);
allBaseObject.push(cube);

const allLights = []; // 所有光源
// 添加环境光（自然光），设置自然光的颜色，设置自然光的强度（0 最暗， 1 最强）
const ambientLight = new AmbientLight("rgb(255,255,255)", 0.8);
allLights.push(ambientLight);
const pointLight = new PointLight(
  'rgb(255,255,255)',
  0.5,
  600,
  0.2
)
pointLight.position.set(0, 100, 200)  // 设置点光源位置 (x,y,z)
allLights.push(pointLight)  // 将点光源添加到光源列表抛出

onMounted(() => {
  threejsContainer.value = new ThreeEngine(threejsContainerRef.value);
  threejsContainer.value.addObject(...allBaseObject);
  threejsContainer.value.addObject(...allLights);
});
</script>

<style lang="less" scoped>
.threejs-container {
  width: 100%;
  height: 100%;
  overflow: hidden;
  background-color: #d6eaff;
}
</style>
